﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ImageProcessing
{
	class CustomMatrix
	{
		double[][] matrix;
		int nRows, nCols;

		public CustomMatrix()
		{
			matrix = new double[][] {
				new double[] {0, 0, 0},
				new double[] {0, 0, 0},
				new double[] {0, 0, 0}
			};
			//matrix = new double[][]
			//{
			//    new double[] { 0.0,0.0,0.0},
			//    new double[] { 0.0,0.0,0.0},
			//    new double[] { 0.0,0.0,0.0}
			//};
			nRows = nCols = 3;
		}


		public CustomMatrix(int rows, int cols)
		{

			matrix = new double[rows][];
			nRows = rows;
			nCols = cols;
			for (int j=0; j < nRows; j++)
			{
					matrix[j] = new double[nCols];
			}
			//initialize to zero
			for (int i = 0; i < nRows; i++)
			{
				for (int j = 0; j < nCols; j++)
				{
					matrix[i][j] = 0.0;
				}
			}


		}
		public CustomMatrix(int rows,int cols, double[] values)
		{
			int len = rows*cols;
			nRows = rows;
			nCols = cols;
			matrix = new double[nRows][];
			for (int j = 0; j < nRows; j++)
			{
				matrix[j] = new double[nCols];
			}
			for (int i = 0; i < len; i++)
			{
				if (i < values.Length )
					matrix[i / nCols][i % nCols] = values[i];
				else
					matrix[i / nCols][i % nCols] = 0.0;
			}
		}

		public static CustomMatrix operator *(CustomMatrix A, CustomMatrix B)
		{
				CustomMatrix C = new CustomMatrix(A.Rows,B.Columns);
				if (A.Columns != B.Rows) return null;
		
				for (int i = 0; i < A.Rows; i++)
				{
					for (int j = 0; j < B.Columns; j++)
					{
						for (int k = 0; k < B.Rows; k++)
						{
							C.matrix[i][j] += A.matrix[i][k] * B.matrix[k][j];
						}
					}
				}
			return C;
		}
		public static CustomMatrix operator *(CustomMatrix A, int[] B)
		{
			CustomMatrix C = new CustomMatrix(A.Rows, B.Length);
			for (int i = 0; i < A.Rows; i++)
			{
				for (int j = 0; j < 1; j++)
				{
					for (int k = 0; k < B.Length; k++)
					{
						C.matrix[i][j] += A.matrix[i][k] * (double)B[k];
					}
				}
			}
			return C;
		}

		public int SetAtLocation(int row, int col, double val)
		{
			if (row > this.Rows || col > this.Columns)
				return -1;

			this.matrix[row][col] = val;
			return 0;
		}

		//returns the minimum value in a given row
		//used to determine the shift value for a rotation
		//value returned as a positive value
		public double Min(int row)
		{
			double min = double.MaxValue;
			for (int i = 0; i < this.Columns; i++)
			{
				if (this.Matrix[row][i] < min)
				{
					min = this.Matrix[row][i];
				}
			}
			return min;
		}

		public double NegMax(int row)
		{
			double max = double.MinValue;
			for (int i = 0; i < this.Columns; i++)
			{
				if ((-this.Matrix[row][i]) > max)
					max = (-this.Matrix[row][i]);
			}
			return max;
		}

		public int Columns
		{
			get { return nCols; }
		}
		public int Rows
		{
			get
			{ return nRows; }
		}
		public double[][] Matrix
		{
			get { return matrix; }
		}
	
		
	}
}
